#include "rtda/heap/field.h"
#include "classfile/class_file.hpp"

namespace jvm {
namespace heap {

Field::Field(std::shared_ptr<Class> pClass, const std::shared_ptr<classfile::MemberInfo> pMemberInfo) {
    m_pClass = pClass;
    copyMemberInfo(pMemberInfo);
    copyAttributes(pMemberInfo);
}

std::vector<std::shared_ptr<Field>> Field::newFields(std::shared_ptr<Class> pClass, const std::vector<std::shared_ptr<classfile::MemberInfo>>& cfFields) {
    std::vector<std::shared_ptr<Field>> fields;
    fields.reserve(cfFields.size());
    
    for (const auto& pMemberInfo : cfFields) {
        fields.push_back(new Field(pClass, pMemberInfo));
    }
    
    return fields;
}

void Field::copyAttributes(const std::shared_ptr<classfile::MemberInfo> pMemberInfo) {
    if (auto pValAttr = pMemberInfo->getConstantValueAttribute()) {
        m_constValueIndex = static_cast<uint>(pValAttr->getConstantValueIndex());
    }
}

bool Field::isVolatile() const { return 0 != (m_accessFlags & ACC_VOLATILE); }
bool Field::isTransient() const { return 0 != (m_accessFlags & ACC_TRANSIENT); }
bool Field::isEnum() const { return 0 != (m_accessFlags & ACC_ENUM); }

uint Field::getConstValueIndex() const { return m_constValueIndex; }
uint Field::getSlotId() const { return m_slotId; }
void Field::setSlotId(uint slotId) { m_slotId = slotId; }

bool Field::isLongOrDouble() const {
    return m_descriptor == "J" || m_descriptor == "D";
}

} // namespace heap
} // namespace jvm